package com.example.apitesttool.service;

import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 固定参数管理器
 * 
 * 负责管理用户设置的固定参数，如 App-Key、Authorization Token 等。
 * 这些参数会在每次 HTTP 请求时自动注入到请求头中。
 * 
 * 特性：
 * - 线程安全的参数存储
 * - 支持参数的增删改查
 * - 自动注入到 HTTP 请求中
 * 
 * @author liuxy
 * @version 1.0.0
 */
@Component
public class FixedParameterManager {
    
    private static final Logger logger = LoggerFactory.getLogger(FixedParameterManager.class);
    
    // 使用 ConcurrentHashMap 存储固定参数，确保线程安全
    private final Map<String, String> fixedParameters = new ConcurrentHashMap<>();

    /**
     * 设置一个固定参数
     * 
     * @param name 参数名称 (例如: "App-Key", "Authorization", "X-API-Token")
     * @param value 参数值
     */
    public void setParameter(String name, String value) {
        if (name == null || name.trim().isEmpty()) {
            logger.warn("尝试设置空的参数名称，操作被忽略");
            return;
        }
        
        if (value == null) {
            logger.warn("尝试设置参数 {} 的值为 null，将被转换为空字符串", name);
            value = "";
        }
        
        String oldValue = fixedParameters.put(name.trim(), value);
        if (oldValue != null) {
            logger.info("更新固定参数: {} (旧值已覆盖)", name);
        } else {
            logger.info("新增固定参数: {}", name);
        }
    }

    /**
     * 获取一个固定参数的值
     * 
     * @param name 参数名称
     * @return 参数值的 Optional，如果不存在则为空
     */
    public Optional<String> getParameter(String name) {
        if (name == null || name.trim().isEmpty()) {
            return Optional.empty();
        }
        return Optional.ofNullable(fixedParameters.get(name.trim()));
    }

    /**
     * 获取所有已设置的固定参数
     * 
     * @return 不可修改的参数 Map
     */
    public Map<String, String> getAllParameters() {
        return Collections.unmodifiableMap(fixedParameters);
    }

    /**
     * 移除一个固定参数
     * 
     * @param name 参数名称
     * @return 如果参数存在并被移除则返回 true，否则返回 false
     */
    public boolean removeParameter(String name) {
        if (name == null || name.trim().isEmpty()) {
            return false;
        }
        
        String removedValue = fixedParameters.remove(name.trim());
        if (removedValue != null) {
            logger.info("移除固定参数: {}", name);
            return true;
        }
        return false;
    }

    /**
     * 清除所有固定参数
     */
    public void clearAllParameters() {
        int count = fixedParameters.size();
        fixedParameters.clear();
        logger.info("清除了 {} 个固定参数", count);
    }

    /**
     * 检查是否存在指定的参数
     * 
     * @param name 参数名称
     * @return 如果参数存在则返回 true
     */
    public boolean hasParameter(String name) {
        if (name == null || name.trim().isEmpty()) {
            return false;
        }
        return fixedParameters.containsKey(name.trim());
    }

    /**
     * 获取当前存储的参数数量
     * 
     * @return 参数数量
     */
    public int getParameterCount() {
        return fixedParameters.size();
    }

    /**
     * 批量设置参数
     * 
     * @param parameters 要设置的参数 Map
     */
    public void setParameters(Map<String, String> parameters) {
        if (parameters == null || parameters.isEmpty()) {
            logger.warn("尝试批量设置空的参数集合，操作被忽略");
            return;
        }
        
        parameters.forEach(this::setParameter);
        logger.info("批量设置了 {} 个固定参数", parameters.size());
    }

    /**
     * 获取参数的格式化字符串表示（用于日志和调试）
     * 
     * @return 格式化的参数字符串
     */
    public String getParametersAsString() {
        if (fixedParameters.isEmpty()) {
            return "无固定参数";
        }
        
        StringBuilder sb = new StringBuilder();
        sb.append("固定参数 (").append(fixedParameters.size()).append(" 个):\n");
        fixedParameters.forEach((key, value) -> {
            // 对敏感信息进行脱敏处理
            String maskedValue = maskSensitiveValue(key, value);
            sb.append("  ").append(key).append(": ").append(maskedValue).append("\n");
        });
        return sb.toString();
    }

    /**
     * 对敏感参数值进行脱敏处理
     * 
     * @param key 参数名
     * @param value 参数值
     * @return 脱敏后的值
     */
    private String maskSensitiveValue(String key, String value) {
        if (value == null || value.length() <= 4) {
            return "****";
        }
        
        // 对可能包含敏感信息的参数进行脱敏
        String lowerKey = key.toLowerCase();
        if (lowerKey.contains("key") || lowerKey.contains("token") || 
            lowerKey.contains("auth") || lowerKey.contains("secret") ||
            lowerKey.contains("password")) {
            return value.substring(0, 2) + "****" + value.substring(value.length() - 2);
        }
        
        return value;
    }
}

